package com.eipc;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class AroundMapActivity extends Activity implements OnTouchListener  {
	   private static final String TAG = "Touch";
	   // These matrices will be used to move and zoom image
	   Matrix matrix = new Matrix();
	   Matrix savedMatrix = new Matrix();
	   //current zoom
	   private float currentScale = 1;

	   // We can be in one of these 3 states
	   static final int NONE = 0;
	   static final int DRAG = 1;
	   static final int ZOOM = 2;
	   int mode = NONE;

	   // Remember some things for zooming
	   PointF start = new PointF();
	   PointF mid = new PointF();
	   float oldDist = 1f;

	   @Override
	   public void onCreate(Bundle savedInstanceState){
	      super.onCreate(savedInstanceState);
	      setContentView(R.layout.map);
	      ImageView view = (ImageView) findViewById(R.id.mapView);
	      // ...
	      // Work around a Cupcake bug
	      matrix.setTranslate(-973f, -254f);
	      view.setImageMatrix(matrix);
	      view.setOnTouchListener(this);
	   }

	   @Override
	   public boolean onTouch(View v, MotionEvent rawEvent) {
	      WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
	      // ...
	      ImageView view = (ImageView) v;

	      // Dump touch event to log
//	      dumpEvent(event);

	      // Handle touch events here...
	      switch (event.getAction()&MotionEvent.ACTION_MASK) {
		      case MotionEvent.ACTION_DOWN:
				         savedMatrix.set(matrix);
				         start.set(event.getX(), event.getY());
				         Log.d(TAG, "mode=DRAG");
				         mode = DRAG;
				         break;
		      case MotionEvent.ACTION_POINTER_DOWN:
				         oldDist = spacing(event);
				         Log.d(TAG, "oldDist=" + oldDist);
				         if (oldDist > 10f) {
				            savedMatrix.set(matrix);
				            midPoint(mid, event);
				            mode = ZOOM;
				            Log.d(TAG, "mode=ZOOM");
				         }
				         break;
		      case MotionEvent.ACTION_UP:
		      case MotionEvent.ACTION_POINTER_UP:
				         mode = NONE;
				         Log.d(TAG, "mode=NONE");
				         break;
		      case MotionEvent.ACTION_MOVE:
				         if (mode == DRAG) {
				            // ...
				            matrix.set(savedMatrix);
//				            Log.d(TAG, String.valueOf(event.getX() - start.x));
//				            Log.d(TAG, String.valueOf(event.getX()));
//				            Log.d(TAG, String.valueOf(event.getY() - start.y));
//				            Log.d(TAG, String.valueOf(event.getY()));
				            matrix.postTranslate(event.getX() - start.x,event.getY() - start.y);
				         }else if (mode == ZOOM) {
				            float newDist = spacing(event);
				            if (newDist > 10f){
				               float scale = newDist/oldDist;
//				               Log.d(TAG, "--------scale=" + scale);
//				               Log.d(TAG, "--------currentScale=" + currentScale);
				               if(currentScale*scale>=0.2&&currentScale*scale<=5){
				            	   matrix.set(savedMatrix);
				            	   currentScale = currentScale*scale;
				            	   matrix.postScale(scale,scale,mid.x,mid.y);
				               }
				            }
				         }
				         break;
	      }

	      view.setImageMatrix(matrix);
	      return true; // indicate event was handled
	   }

	   /** Show an event in the LogCat view, for debugging */
	   private void dumpEvent(WrapMotionEvent event) {
	      // ...
	      String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE","POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
	      StringBuilder sb = new StringBuilder();
	      int action = event.getAction();
	      int actionCode = action & MotionEvent.ACTION_MASK;
	      sb.append("event ACTION_").append(names[actionCode]);
	      if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) {
	         sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
	         sb.append(")");
	      }
	      sb.append("[");
	      for (int i = 0; i < event.getPointerCount(); i++) {
	         sb.append("#").append(i);
	         sb.append("(pid ").append(event.getPointerId(i));
	         sb.append(")=").append((int) event.getX(i));
	         sb.append(",").append((int) event.getY(i));
	         if(i + 1 < event.getPointerCount())sb.append(";");
	      }
	      sb.append("]");
//	      Log.d(TAG, sb.toString());
	   }

	   /** Determine the space between the first two fingers */
	   private float spacing(WrapMotionEvent event) {
	      // ...
	      float x = event.getX(0) - event.getX(1);
	      float y = event.getY(0) - event.getY(1);
	      return FloatMath.sqrt(x * x + y * y);
	   }

	   /** Calculate the mid point of the first two fingers */
	   private void midPoint(PointF point, WrapMotionEvent event) {
	      // ...
	      float x = event.getX(0) + event.getX(1);
	      float y = event.getY(0) + event.getY(1);
	      point.set(x / 2, y / 2);
	   }
	}
